<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 5.2.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="/lib/font-awesome/css/all.min.css">

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"llmysnow.top","root":"/","scheme":"Gemini","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":true,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":true},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},"path":"search.xml"};
  </script>

  <meta name="description" content="观看视频：尚硅谷最新版Webpack5实战教程(从入门到精通)">
<meta property="og:type" content="article">
<meta property="og:title" content="Webpack（优化和问题）">
<meta property="og:url" content="http://llmysnow.top/posts/4317de95/index.html">
<meta property="og:site_name" content="奇幻的梦之旅">
<meta property="og:description" content="观看视频：尚硅谷最新版Webpack5实战教程(从入门到精通)">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2021-08-27T07:40:55.162Z">
<meta property="article:modified_time" content="2021-08-27T08:02:40.421Z">
<meta property="article:author" content="LiLyn">
<meta property="article:tag" content="Vue">
<meta property="article:tag" content="问题">
<meta property="article:tag" content="优化">
<meta property="article:tag" content="webpack">
<meta name="twitter:card" content="summary">

<link rel="canonical" href="http://llmysnow.top/posts/4317de95/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : false,
    isPost : true,
    lang   : 'zh-CN'
  };
</script>

  <title>Webpack（优化和问题） | 奇幻的梦之旅</title>
  






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

<link rel="alternate" href="/atom.xml" title="奇幻的梦之旅" type="application/atom+xml">
</head>
<!--即时预加载技术，在用户点击之前预先加载页面-->
<script src="https://cdn.jsdelivr.net/gh/TRHX/CDN-for-itrhx.com@2.0.2/js/instantclick-1.2.2.js" type="module"></script>
<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>
	  <!--<a target="_blank" rel="noopener" href="https://github.com/llwodexue" class="github-corner" aria-label="View source on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>-->
    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <h1 class="site-title">奇幻的梦之旅</h1>
      <span class="logo-line-after"><i></i></span>
    </a>
      <p class="site-subtitle" itemprop="description">http://llmysnow.top/</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>




<nav class="site-nav">
  <ul id="menu" class="main-menu menu">
        <li class="menu-item menu-item-home">

    <a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a>

  </li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup">
        <div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div id="search-result">
  <div id="no-result">
    <i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>
  </div>
</div>

    </div>
  </div>

</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content post posts-expand">
            

    
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://llmysnow.top/posts/4317de95/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/logo.jpg">
      <meta itemprop="name" content="LiLyn">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="奇幻的梦之旅">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          Webpack（优化和问题）
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2021-08-27 15:40:55" itemprop="dateCreated datePublished" datetime="2021-08-27T15:40:55+08:00">2021-08-27</time>
            </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/%E5%B7%A5%E7%A8%8B%E5%8C%96/" itemprop="url" rel="index"><span itemprop="name">工程化</span></a>
                </span>
            </span>

          <br>
            <span class="post-meta-item" title="本文字数">
              <span class="post-meta-item-icon">
                <i class="far fa-file-word"></i>
              </span>
                <span class="post-meta-item-text">本文字数：</span>
              <span>26k</span>
            </span>
            <span class="post-meta-item" title="阅读时长">
              <span class="post-meta-item-icon">
                <i class="far fa-clock"></i>
              </span>
                <span class="post-meta-item-text">阅读时长 &asymp;</span>
              <span>23 分钟</span>
            </span>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <p>观看视频：<a target="_blank" rel="noopener" href="https://www.bilibili.com/video/BV1e7411j7T5?p=24&spm_id_from=pageDriver">尚硅谷最新版Webpack5实战教程(从入门到精通)</a></p>
<a id="more"></a>

<h2 id="Webpack-简介"><a href="#Webpack-简介" class="headerlink" title="Webpack 简介"></a>Webpack 简介</h2><h3 id="webpack-是什么"><a href="#webpack-是什么" class="headerlink" title="webpack 是什么"></a>webpack 是什么</h3><p>webpack 是一种 <strong>前端资源构建工具</strong> ，一个静态模块打包器（module bundler）</p>
<p>在 webpack 看来，前端的所有资源文件（js/json/css/img/less…）都会作为模块处理。它将根据模块的依赖关系进行静态分析，打包生成对应的静态资源（bundle）。</p>
<h3 id="webpack-五个核心概念"><a href="#webpack-五个核心概念" class="headerlink" title="webpack 五个核心概念"></a>webpack 五个核心概念</h3><ol>
<li><p>Entry</p>
<p>入口，指示 webpack 以哪个文件作为入口起点开始打包，分析构建内部依赖图</p>
</li>
<li><p>Output</p>
<p>输出，指示 webpack 打包后的资源 bundles 输出到哪里去，以及如何命名</p>
</li>
<li><p>Loader</p>
<p>让 webpack 能够去处理那些非 JavaScript 文件（webpack 自身只理解 JavaScript）</p>
</li>
<li><p>Plugins</p>
<p>可以用于执行范围更广的任务。插件的范围包括，从打包优化和压缩，一直到重新定义环境中的变量等</p>
</li>
<li><p>Mode</p>
<table>
<thead>
<tr>
<th>选项</th>
<th>描述</th>
<th>特点</th>
</tr>
</thead>
<tbody><tr>
<td>development</td>
<td>会将 DefinePlugin 中的 process.env.NODE_ENV 的值设为 development</td>
<td>能让代码本地调试运行的环境</td>
</tr>
<tr>
<td>production</td>
<td>会将 DefinePlugin 中的 process.env.NODE_ENV 的值设为 production</td>
<td>能将代码优化上线运行的环境</td>
</tr>
</tbody></table>
</li>
</ol>
<h2 id="Webpack-初体验"><a href="#Webpack-初体验" class="headerlink" title="Webpack 初体验"></a>Webpack 初体验</h2><h3 id="初始化配置"><a href="#初始化配置" class="headerlink" title="初始化配置"></a>初始化配置</h3><ol>
<li><p>初始化 package.json：npm init</p>
</li>
<li><p>下载安装 webpack：（webpack4 以上的版本需要全局/本地都安装 webpack-cli）</p>
<p>全局安装：<code>npm i webpack@4 webpack-cli@3 -g</code></p>
<p>本地安装：<code>npm i webpack@4 webpack-cli@3 -D</code></p>
</li>
</ol>
<h3 id="编译打包应用"><a href="#编译打包应用" class="headerlink" title="编译打包应用"></a>编译打包应用</h3><p>运行指令：</p>
<ul>
<li>开发环境：<code>webpack ./src/index.js -o ./build/built.js --mode=development</code>，webpack 会以 <code>./src/index.js</code> 为入口文件开始打包，打包后输出到 <code>./build/built.js</code> 整体打包环境，是开发环境</li>
<li>生产环境：<code>webpack ./src/index.js -o ./build/built.js --mode=production</code>，webpack 会以 <code>./src/index.js</code> 为入口文件开始打包，打包后输出到 <code>./build/built.js</code> 整体打包环境，是生产环境</li>
</ul>
<p>结论：</p>
<ol>
<li>webpack 能处理 js、json，不能处理 css、img等其他资源</li>
<li>生产环境和开发环境将 ES6 模块化编译成浏览器能识别的模块化</li>
<li>生产环境比开发环境多一个压缩 JS 代码</li>
</ol>
<h2 id="Webpack-环境的基本配置"><a href="#Webpack-环境的基本配置" class="headerlink" title="Webpack 环境的基本配置"></a>Webpack 环境的基本配置</h2><p><code>webpack.config.js</code> 是 webpack 的配置文件</p>
<ul>
<li>作用：指示 webpack 干哪些活（当你运行 webpack 指令时，会加载里面的配置）</li>
<li>所有构建工具都是基于 nodejs 平台运行的，模块化采用 commonjs</li>
</ul>
<p>path 模块的 resolve <code>__dirname</code> nodejs 的变量，代表当前文件的目录的绝对路径</p>
<p>loader，rules 下的 use 数组中 loader 执行顺序：从右到左、从下到上依次执行</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">npm i less-loader@6 style-loader css-loader@ -D</span><br><span class="line">npm i html-webpack-plugin@4 -D</span><br><span class="line">npm i url-loader file-loader -D</span><br><span class="line">npm i html-loader@0.5 -D</span><br><span class="line">npm i webpack-dev-server -D</span><br></pre></td></tr></table></figure>

<p><code>url-loader</code> 只能处理样式中的图片资源，这个 loader 对图片资源进行 ES6Module 引入 ，为了跟 <code>html-loader</code> 一致，需关闭 ES6Module（<code>esModule :false</code>）</p>
<ul>
<li><p>可以做图片 base64 处理</p>
<p>优点：减少请求数量（减轻服务器压力）</p>
<p>缺点：图片体积会更大（文件请求速度更慢）</p>
</li>
</ul>
<p><code>html-loader</code> 处理html中的图片资源，这个 loader 对图片资源进行 commonJS 引入 </p>
<p>devServer：<code>npx webpack-dev-server</code></p>
<p>开发服务器devServer：用来自动化（自动编译，自动打开浏览器，自动刷新浏览器）。特点：只会在内存中编译打包，不会有任何输出</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> &#123; resolve &#125; = <span class="built_in">require</span>(<span class="string">&#x27;path&#x27;</span>)</span><br><span class="line"><span class="keyword">const</span> HtmlWebpackPlugin = <span class="built_in">require</span>(<span class="string">&#x27;html-webpack-plugin&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">  <span class="comment">// 入口起点</span></span><br><span class="line">  entry: <span class="string">&#x27;./src/index.js&#x27;</span>,</span><br><span class="line">  <span class="comment">// 输出</span></span><br><span class="line">  output: &#123;</span><br><span class="line">    <span class="comment">// 输出文件名</span></span><br><span class="line">    filename: <span class="string">&#x27;built.js&#x27;</span>,</span><br><span class="line">    <span class="comment">// 输出路径</span></span><br><span class="line">    path: resolve(__dirname, <span class="string">&#x27;build&#x27;</span>),</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="comment">// loader配置</span></span><br><span class="line">  <span class="built_in">module</span>: &#123;</span><br><span class="line">    rules: [</span><br><span class="line">      <span class="comment">// 详细loader配置，不同文件必须配置不同loader处理</span></span><br><span class="line">      &#123;</span><br><span class="line">        <span class="comment">// 匹配哪些文件</span></span><br><span class="line">        test: <span class="regexp">/\.css$/</span>,</span><br><span class="line">        <span class="comment">// 使用哪些loader进行处理</span></span><br><span class="line">        use: [</span><br><span class="line">          <span class="comment">// 创建style标签，将js中的样式资源插入，添加到head中生效</span></span><br><span class="line">          <span class="string">&#x27;style-loader&#x27;</span>,</span><br><span class="line">          <span class="comment">// 将css文件变成commonjs模块加载js中，里面内容是样式字符串</span></span><br><span class="line">          <span class="string">&#x27;css-loader&#x27;</span>,</span><br><span class="line">        ],</span><br><span class="line">      &#125;,</span><br><span class="line">      &#123;</span><br><span class="line">        test: <span class="regexp">/\.less$/</span>,</span><br><span class="line">        use: [</span><br><span class="line">          <span class="string">&#x27;style-loader&#x27;</span>,</span><br><span class="line">          <span class="string">&#x27;css-loader&#x27;</span>,</span><br><span class="line">          <span class="comment">// 将less文件编译成css文件</span></span><br><span class="line">          <span class="string">&#x27;less-loader&#x27;</span>,</span><br><span class="line">        ],</span><br><span class="line">      &#125;,</span><br><span class="line">      &#123;</span><br><span class="line">        <span class="comment">// 问题：默认处理不了html中img图片</span></span><br><span class="line">        <span class="comment">// 处理图片资源</span></span><br><span class="line">        test: <span class="regexp">/\.(jpg|png|gif)$/</span>,</span><br><span class="line">        loader: <span class="string">&#x27;url-loader&#x27;</span>,</span><br><span class="line">        options: &#123;</span><br><span class="line">          <span class="comment">// 图片大小小于8kb，就会被base64处理</span></span><br><span class="line">          limit: <span class="number">8</span> * <span class="number">1024</span>,</span><br><span class="line">          esModule: <span class="literal">false</span>,</span><br><span class="line">          <span class="comment">// 给图片进行重命名</span></span><br><span class="line">          name: <span class="string">&#x27;[hash:10].[ext]&#x27;</span>,</span><br><span class="line">        &#125;,</span><br><span class="line">      &#125;,</span><br><span class="line">      &#123;</span><br><span class="line">        test: <span class="regexp">/\.html$/</span>,</span><br><span class="line">        <span class="comment">// 处理html文件的img图片（负责引入img，从而能被url-loader处理）</span></span><br><span class="line">        loader: <span class="string">&#x27;html-loader&#x27;</span>,</span><br><span class="line">      &#125;,</span><br><span class="line">      &#123;</span><br><span class="line">        <span class="comment">// 排除css/js/html资源</span></span><br><span class="line">        exclude: <span class="regexp">/\.(css|js|less|jpg|png|gif|html)$/</span>,</span><br><span class="line">        loader: <span class="string">&#x27;file-loader&#x27;</span>,</span><br><span class="line">        options: &#123;</span><br><span class="line">          name: <span class="string">&#x27;[hash:10].[ext]&#x27;</span>,</span><br><span class="line">        &#125;,</span><br><span class="line">      &#125;,</span><br><span class="line">    ],</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="comment">// plugins配置</span></span><br><span class="line">  plugins: [</span><br><span class="line">    <span class="comment">// 详细plugins配置</span></span><br><span class="line">    <span class="comment">// 默认会创建一个空的html，引入打包输出的所有资源（JS/CSS）</span></span><br><span class="line">    <span class="keyword">new</span> HtmlWebpackPlugin(&#123;</span><br><span class="line">      <span class="comment">// 复制 &#x27;./src/index.html&#x27; 文件，并自动引入打包输出的所有资源（JS/CSS）</span></span><br><span class="line">      template: <span class="string">&#x27;./src/index.html&#x27;</span>,</span><br><span class="line">    &#125;),</span><br><span class="line">  ],</span><br><span class="line">  <span class="comment">// 模式</span></span><br><span class="line">  mode: <span class="string">&#x27;development&#x27;</span>, <span class="comment">// 开发模式</span></span><br><span class="line">  <span class="comment">// mode: &#x27;production&#x27;, // 生产模式</span></span><br><span class="line">  devServer: &#123;</span><br><span class="line">    <span class="comment">// 项目构建后路径</span></span><br><span class="line">    contentBase: resolve(__dirname, <span class="string">&#x27;build&#x27;</span>),</span><br><span class="line">    <span class="comment">// 启动gzip压缩</span></span><br><span class="line">    compress: <span class="literal">true</span>,</span><br><span class="line">    <span class="comment">// 端口号</span></span><br><span class="line">    port: <span class="number">3000</span>,</span><br><span class="line">    <span class="comment">// 自动打开浏览器</span></span><br><span class="line">    open: <span class="literal">true</span>,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="Webpack-生产环境的基本配置"><a href="#Webpack-生产环境的基本配置" class="headerlink" title="Webpack 生产环境的基本配置"></a>Webpack 生产环境的基本配置</h2><p><a target="_blank" rel="noopener" href="https://github.com/topics/javascript">https://github.com/topics/javascript</a></p>
<ul>
<li>安装</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">npm i mini-css-extract-plugin -D</span><br><span class="line">npm i postcss-loader@3 postcss-preset-env -D</span><br><span class="line">npm i optimize-css-assets-webpack-plugin -D</span><br><span class="line">npm i eslint eslint-loader eslint-plugin-import eslint-config-airbnb-base -D</span><br><span class="line">npm i babel-loader @babel/core @babel/preset-env -D</span><br><span class="line">npm i @babel/polyfill -D</span><br><span class="line">npm i core-js -D</span><br><span class="line">npm i rimraf -D</span><br></pre></td></tr></table></figure>

<ul>
<li><p>压缩一般使用 plugin 完成</p>
<p>兼容一般使用 loader 完成</p>
</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> HtmlWebpackPlugin = <span class="built_in">require</span>(<span class="string">&#x27;html-webpack-plugin&#x27;</span>)</span><br><span class="line"><span class="keyword">const</span> &#123; resolve &#125; = <span class="built_in">require</span>(<span class="string">&#x27;path&#x27;</span>)</span><br><span class="line"><span class="keyword">const</span> MiniCssExtractPlugin = <span class="built_in">require</span>(<span class="string">&#x27;mini-css-extract-plugin&#x27;</span>)</span><br><span class="line"><span class="keyword">const</span> OptimizeCssAssetsWebpackPlugin = <span class="built_in">require</span>(<span class="string">&#x27;optimize-css-assets-webpack-plugin&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 定义nodejs环境变量，决定使用browserslist的哪个环境</span></span><br><span class="line">process.env.NODE_ENV = <span class="string">&#x27;production&#x27;</span></span><br><span class="line"><span class="keyword">const</span> commonCssLoader = [</span><br><span class="line">  <span class="comment">// 这个loader取代style-loader。作用：提取js中的css成单独文件</span></span><br><span class="line">  MiniCssExtractPlugin.loader,</span><br><span class="line">  <span class="comment">// 将css文件整合到js文件中</span></span><br><span class="line">  <span class="string">&#x27;css-loader&#x27;</span>,</span><br><span class="line">  <span class="comment">// 帮助postcss找到package.json中browserslist里面的配置，通过配置价值指定的css兼容性样式</span></span><br><span class="line">  &#123;</span><br><span class="line">    loader: <span class="string">&#x27;postcss-loader&#x27;</span>,</span><br><span class="line">    options: &#123;</span><br><span class="line">      ident: <span class="string">&#x27;postcss&#x27;</span>,</span><br><span class="line">      plugins: <span class="function">() =&gt;</span> [<span class="built_in">require</span>(<span class="string">&#x27;postcss-preset-env&#x27;</span>)()],</span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;,</span><br><span class="line">]</span><br><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">  entry: <span class="string">&#x27;./src/js/index.js&#x27;</span>,</span><br><span class="line">  output: &#123;</span><br><span class="line">    filename: <span class="string">&#x27;js/built.js&#x27;</span>,</span><br><span class="line">    path: resolve(__dirname, <span class="string">&#x27;build&#x27;</span>),</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="built_in">module</span>: &#123;</span><br><span class="line">    rules: [</span><br><span class="line">      &#123;</span><br><span class="line">        test: <span class="regexp">/\.css$/</span>,</span><br><span class="line">        use: [...commonCssLoader],</span><br><span class="line">      &#125;,</span><br><span class="line">      &#123;</span><br><span class="line">        test: <span class="regexp">/\.less$/</span>,</span><br><span class="line">        use: [...commonCssLoader, <span class="string">&#x27;less-loader&#x27;</span>],</span><br><span class="line">      &#125;,</span><br><span class="line">      <span class="comment">// 语法检查。注意：只检查自己写的源代码</span></span><br><span class="line">      <span class="comment">/* &#123;</span></span><br><span class="line"><span class="comment">        test: /\.js$/,</span></span><br><span class="line"><span class="comment">        exclude: /node_modules/,</span></span><br><span class="line"><span class="comment">        loader: &#x27;eslint-loader&#x27;,</span></span><br><span class="line"><span class="comment">        options: &#123;</span></span><br><span class="line"><span class="comment">          // 优先执行</span></span><br><span class="line"><span class="comment">          enforce: &#x27;pre&#x27;,</span></span><br><span class="line"><span class="comment">          // 自动修复eslint错误</span></span><br><span class="line"><span class="comment">          fix: true,</span></span><br><span class="line"><span class="comment">        &#125;,</span></span><br><span class="line"><span class="comment">      &#125;, */</span></span><br><span class="line">      <span class="comment">// 基本js兼容性处理 -&gt; @babel/preset-env</span></span><br><span class="line">      &#123;</span><br><span class="line">        test: <span class="regexp">/\.js$/</span>,</span><br><span class="line">        exclude: <span class="regexp">/node_modules/</span>,</span><br><span class="line">        loader: <span class="string">&#x27;babel-loader&#x27;</span>,</span><br><span class="line">        options: &#123;</span><br><span class="line">          <span class="comment">// 预设：指示babel做怎么样的兼容性处理</span></span><br><span class="line">          presets: [</span><br><span class="line">            [</span><br><span class="line">              <span class="string">&#x27;@babel/preset-env&#x27;</span>,</span><br><span class="line">              &#123;</span><br><span class="line">                <span class="comment">// 按需加载</span></span><br><span class="line">                useBuiltIns: <span class="string">&#x27;usage&#x27;</span>,</span><br><span class="line">                <span class="comment">// 指定core-js版本</span></span><br><span class="line">                corejs: &#123;</span><br><span class="line">                  version: <span class="number">3</span>,</span><br><span class="line">                &#125;,</span><br><span class="line">                <span class="comment">// 指定兼容性做到哪个版本浏览器</span></span><br><span class="line">                targets: &#123;</span><br><span class="line">                  chrome: <span class="string">&#x27;60&#x27;</span>,</span><br><span class="line">                  ie: <span class="string">&#x27;9&#x27;</span>,</span><br><span class="line">                  safari: <span class="string">&#x27;10&#x27;</span>,</span><br><span class="line">                &#125;,</span><br><span class="line">              &#125;,</span><br><span class="line">            ],</span><br><span class="line">          ],</span><br><span class="line">        &#125;,</span><br><span class="line">      &#125;,</span><br><span class="line">    ],</span><br><span class="line">  &#125;,</span><br><span class="line">  plugins: [</span><br><span class="line">    <span class="keyword">new</span> HtmlWebpackPlugin(&#123;</span><br><span class="line">      template: <span class="string">&#x27;./src/index.html&#x27;</span>,</span><br><span class="line">      minify: &#123;</span><br><span class="line">        <span class="comment">// 移除空格</span></span><br><span class="line">        collapseWhitespace: <span class="literal">true</span>,</span><br><span class="line">        <span class="comment">// 移除注释</span></span><br><span class="line">        removeComments: <span class="literal">true</span>,</span><br><span class="line">      &#125;,</span><br><span class="line">    &#125;),</span><br><span class="line">    <span class="keyword">new</span> MiniCssExtractPlugin(&#123;</span><br><span class="line">      <span class="comment">// 对输出的css文件进行重命名</span></span><br><span class="line">      filename: <span class="string">&#x27;css/built.css&#x27;</span>,</span><br><span class="line">    &#125;),</span><br><span class="line">    <span class="comment">// 压缩css</span></span><br><span class="line">    <span class="keyword">new</span> OptimizeCssAssetsWebpackPlugin(),</span><br><span class="line">  ],</span><br><span class="line">  <span class="comment">// 生产模式js自动压缩</span></span><br><span class="line">  mode: <span class="string">&#x27;production&#x27;</span>,</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="css-兼容性处理"><a href="#css-兼容性处理" class="headerlink" title="css 兼容性处理"></a>css 兼容性处理</h3><p><code>package.json</code> 中的 <code>browserslist</code> 配置</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">&quot;browserslist&quot;: &#123;</span><br><span class="line">  &quot;development&quot;: [</span><br><span class="line">    &quot;last 1 chrome version&quot;,</span><br><span class="line">    &quot;last 1 firefox version&quot;,</span><br><span class="line">    <span class="string">&quot;last 1 safari version&quot;</span></span><br><span class="line">  ],</span><br><span class="line">  &quot;production&quot;: [</span><br><span class="line">    &quot;&gt;0.2%&quot;,</span><br><span class="line">    &quot;not dead&quot;,</span><br><span class="line">    <span class="string">&quot;not op_mini all&quot;</span></span><br><span class="line">  ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><code>MiniCssExtractPlugin</code> 提取js中的css成单独文件</p>
<p><code>OptimizeCssAssetsWebpackPlugin</code> 对 css 代码进行压缩</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  test: <span class="regexp">/\.css$/</span>,</span><br><span class="line">  use: [</span><br><span class="line">    MiniCssExtractPlugin.loader,</span><br><span class="line">    <span class="comment">// 帮助postcss找到package.json中browserslist里面的配置，通过配置价值指定的css兼容性样式</span></span><br><span class="line">    &#123;</span><br><span class="line">      loader: <span class="string">&#x27;postcss-loader&#x27;</span>,</span><br><span class="line">      options: &#123;</span><br><span class="line">        ident: <span class="string">&#x27;postcss&#x27;</span>,</span><br><span class="line">        plugins: <span class="function">() =&gt;</span> [</span><br><span class="line">          <span class="built_in">require</span>(<span class="string">&#x27;postcss-preset-env&#x27;</span>)(),</span><br><span class="line">        ],</span><br><span class="line">      &#125;,</span><br><span class="line">    &#125;,</span><br><span class="line">  ],</span><br><span class="line">&#125;,</span><br><span class="line">plugins: [</span><br><span class="line">  <span class="keyword">new</span> MiniCssExtractPlugin(&#123;</span><br><span class="line">    <span class="comment">// 对输出的css文件进行重命名</span></span><br><span class="line">    filename: <span class="string">&#x27;css/built.css&#x27;</span>,</span><br><span class="line">  &#125;),</span><br><span class="line">  <span class="comment">// 压缩css</span></span><br><span class="line">  <span class="keyword">new</span> OptimizeCssAssetsWebpackPlugin(),</span><br><span class="line">],</span><br></pre></td></tr></table></figure>

<h3 id="eslint-语法检查"><a href="#eslint-语法检查" class="headerlink" title="eslint 语法检查"></a>eslint 语法检查</h3><p><code>package.json</code> 中的 <code>eslintConfig</code> 配置</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&quot;eslintConfig&quot;: &#123;</span><br><span class="line">  &quot;extends&quot;: &quot;airbnb-base&quot;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>使用 <code>eslint-loader</code> 自动修复</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  test: <span class="regexp">/\.js$/</span>,</span><br><span class="line">  exclude: <span class="regexp">/node_modules/</span>,</span><br><span class="line">  loader: <span class="string">&#x27;eslint-loader&#x27;</span>,</span><br><span class="line">  options: &#123;</span><br><span class="line">    <span class="comment">// 自动修复eslint错误</span></span><br><span class="line">    fix: <span class="literal">true</span>,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>

<h3 id="js-兼容性处理"><a href="#js-兼容性处理" class="headerlink" title="js 兼容性处理"></a>js 兼容性处理</h3><p>首先需要安装 <code>babel-loader</code> 、 <code>@babel/core</code></p>
<ol>
<li><p>基本 js 兼容处理 -&gt; <code>@babel/preset-env</code></p>
<p>问题：只能转换基本语法，比如：promise 不能转换</p>
</li>
<li><p>全部 js 兼容性处理 -&gt; <code>@babel/polyfill</code></p>
<p>在 js 中引入<code>import &#39;@babel/polyfill&#39;</code></p>
<p>问题：只要解决部分兼容性问题，但是所有兼容性代码全部引入，体积太大</p>
</li>
<li><p>按需加载 js 兼容性处理</p>
<p>使用 <code>core-js</code></p>
<p>或使用 link 引入<code>https://polyfill.io/v3/url-builder/</code></p>
</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  test: <span class="regexp">/\.js$/</span>,</span><br><span class="line">  exclude: <span class="regexp">/node_modules/</span>,</span><br><span class="line">  loader: <span class="string">&#x27;babel-loader&#x27;</span>,</span><br><span class="line">  options: &#123;</span><br><span class="line">    <span class="comment">// 预设：指示babel做怎么样的兼容性处理</span></span><br><span class="line">    presets: [</span><br><span class="line">      [</span><br><span class="line">        <span class="string">&#x27;@babel/preset-env&#x27;</span>,</span><br><span class="line">        &#123;</span><br><span class="line">          <span class="comment">// 按需加载</span></span><br><span class="line">          useBuiltIns: <span class="string">&#x27;usage&#x27;</span>,</span><br><span class="line">          <span class="comment">// 指定core-js版本</span></span><br><span class="line">          corejs: &#123;</span><br><span class="line">            version: <span class="number">3</span>,</span><br><span class="line">          &#125;,</span><br><span class="line">          <span class="comment">// 指定兼容性做到哪个版本浏览器</span></span><br><span class="line">          targets: &#123;</span><br><span class="line">            chrome: <span class="string">&#x27;60&#x27;</span>,</span><br><span class="line">            firefox: <span class="string">&#x27;60&#x27;</span>,</span><br><span class="line">            ie: <span class="string">&#x27;9&#x27;</span>,</span><br><span class="line">            safari: <span class="string">&#x27;10&#x27;</span>,</span><br><span class="line">            edge: <span class="string">&#x27;17&#x27;</span>,</span><br><span class="line">          &#125;,</span><br><span class="line">        &#125;,</span><br><span class="line">      ],</span><br><span class="line">    ],</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>

<h3 id="html-压缩"><a href="#html-压缩" class="headerlink" title="html 压缩"></a>html 压缩</h3><p>生产环境会自动压缩 js 代码（默认加载 <code>UglifyJsPlugin</code>）</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">plugins: [</span><br><span class="line">  <span class="keyword">new</span> HtmlWebpackPlugin(&#123;</span><br><span class="line">    template: <span class="string">&#x27;./src/index.html&#x27;</span>,</span><br><span class="line">    minify: &#123;</span><br><span class="line">      <span class="comment">// 移除空格</span></span><br><span class="line">      collapseWhitespace: <span class="literal">true</span>,</span><br><span class="line">      <span class="comment">// 移除注释</span></span><br><span class="line">      removeComments: <span class="literal">true</span>,</span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;),</span><br><span class="line">  <span class="keyword">new</span> MiniCssExtractPlugin(&#123;</span><br><span class="line">    filename: <span class="string">&#x27;css/built.css&#x27;</span>,</span><br><span class="line">  &#125;),</span><br><span class="line">  <span class="keyword">new</span> OptimizeCssAssetsWebpackPlugin(),</span><br><span class="line">],</span><br></pre></td></tr></table></figure>

<h2 id="Webpack-优化配置"><a href="#Webpack-优化配置" class="headerlink" title="Webpack 优化配置"></a>Webpack 优化配置</h2><h3 id="开发环境性能优化"><a href="#开发环境性能优化" class="headerlink" title="开发环境性能优化"></a>开发环境性能优化</h3><h4 id="HMR：（优化打包构建速度）"><a href="#HMR：（优化打包构建速度）" class="headerlink" title="HMR：（优化打包构建速度）"></a>HMR：（优化打包构建速度）</h4><p>HMR（hot module replacement）热模块替换 / 模块热替换</p>
<p>作用：一个模块发生变化，只会重新打包这一个模块（而不是所有模块）。极大提高构建速度</p>
<ol>
<li><p>样式文件，可以使用 HMR 功能，因为 <code>style-loader</code> 内部实现了（比如引入 <code>style-loader</code>）</p>
</li>
<li><p>js 文件，默认不能使用 HMR 功能 -&gt;  需要修改 js 代码，添加支持 HMR 功能代码</p>
<p>注意：HMR 功能对 js 处理，只能处理非入口 js 文件的其他文件</p>
</li>
<li><p>html 文件，默认不能使用 HMR 功能，同时导致问题：html 文件不能热更新（不用做 HMR 功能）</p>
<p>解决方法：修改 entry 入口，将 html 文件引入</p>
</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">devServer: &#123;</span><br><span class="line">  <span class="comment">// 开启HMR功能</span></span><br><span class="line">  hot: <span class="literal">true</span>,</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>

<h4 id="source-map：（优化代码调试）"><a href="#source-map：（优化代码调试）" class="headerlink" title="source-map：（优化代码调试）"></a>source-map：（优化代码调试）</h4><p>一种提供 <strong>源代码到构建后代码的映射</strong> 的技术（如果构建后代码出错了，通过映射可以追溯源代码错误）</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// [inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 外部。提示的是错误代码准确信息和源代码的错误位置</span></span><br><span class="line">devtool: <span class="string">&#x27;source-map&#x27;</span></span><br><span class="line"><span class="comment">// 内联：只生成一个内联source-map。提示的是错误代码准确信息和源代码的错误位置</span></span><br><span class="line">devtool: <span class="string">&#x27;inline-source-map&#x27;</span></span><br><span class="line"><span class="comment">// 外部。提示的是错误代码准确信息但是没有错误位置（不能追踪源代码错误，只能提示到构建后代码的错误位置）</span></span><br><span class="line">devtool: <span class="string">&#x27;hidden-source-map&#x27;</span></span><br><span class="line"><span class="comment">// 内联：每一个文件都生成对应的source-map，都在eval。提示的是错误代码准确信息和源代码的错误位置</span></span><br><span class="line">devtool: <span class="string">&#x27;eval-source-map&#x27;</span></span><br><span class="line"><span class="comment">// 外部。提示的是错误代码准确信息但是没有任何源代码信息</span></span><br><span class="line">devtool: <span class="string">&#x27;nosources-source-map&#x27;</span></span><br><span class="line"><span class="comment">// 外部。提示的是错误代码准确信息和源代码的错误位置（只能精确到行，其余能精确到准确位置）</span></span><br><span class="line">devtool: <span class="string">&#x27;cheap-source-map&#x27;</span></span><br><span class="line"><span class="comment">// 外部。提示的是错误代码准确信息和源代码的错误位置。module会将loader的source-map加入</span></span><br><span class="line">devtool: <span class="string">&#x27;cheap-module-source-map&#x27;</span></span><br></pre></td></tr></table></figure>

<p>内联和外部的区别：</p>
<ol>
<li>外部生成了文件，内联没有</li>
<li>内联构建速度更快</li>
</ol>
<p>开发环境：速度快，调试更友好</p>
<ul>
<li><p>速度快（eval&gt;inline&gt;cheap&gt;…）</p>
<p>eval-cheap-source-map</p>
<p>eval-source-map</p>
</li>
<li><p>调试更友好</p>
<p>source-map</p>
<p>cheap-module-source-map</p>
<p>cheap-source-map</p>
</li>
<li><p><strong>推荐：eval-source-map（脚手架默认使用这个；完整度高，内联速度快）、eval-cheap-module-source-map（错误提示忽略列但是包含其他信息，内联速度快）</strong></p>
</li>
</ul>
<p>生产环境：源代码要不要隐藏？调试要不要更友好</p>
<ul>
<li><p>内联会让代码体积大，所以生产环境不用内联</p>
<p>nosources-source-map 全部隐藏</p>
<p>hidden-source-map 只隐藏源代码</p>
<p>source-map</p>
</li>
<li><p><strong>推荐：source-map（最完整）、cheap-module-source-map（错误提示一整行忽略列）</strong></p>
</li>
</ul>
<h3 id="生产环境性能优化"><a href="#生产环境性能优化" class="headerlink" title="生产环境性能优化"></a>生产环境性能优化</h3><h4 id="oneOf：惰性匹配（优化打包构建速度）"><a href="#oneOf：惰性匹配（优化打包构建速度）" class="headerlink" title="oneOf：惰性匹配（优化打包构建速度）"></a>oneOf：惰性匹配（优化打包构建速度）</h4><p>匹配到 loader 后就不会再向后进行匹配，提升性能</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">rules: [</span><br><span class="line">  &#123;</span><br><span class="line">    <span class="comment">// 注意：不能有两个配置处理同一个文件</span></span><br><span class="line">    oneOf: [</span><br><span class="line">      &#123;</span><br><span class="line">        test: <span class="regexp">/\.less$/</span>,</span><br><span class="line">        use: [<span class="string">&#x27;style-loader&#x27;</span>, <span class="string">&#x27;css-loader&#x27;</span>, <span class="string">&#x27;less-loader&#x27;</span>],</span><br><span class="line">      &#125;,</span><br><span class="line">      &#123;</span><br><span class="line">        test: <span class="regexp">/\.css$/</span>,</span><br><span class="line">        use: [<span class="string">&#x27;style-loader&#x27;</span>, <span class="string">&#x27;css-loader&#x27;</span>],</span><br><span class="line">      &#125;,</span><br><span class="line">    ],</span><br><span class="line">  &#125;,</span><br><span class="line">],</span><br></pre></td></tr></table></figure>

<h4 id="多线程打包：（优化打包构建速度）"><a href="#多线程打包：（优化打包构建速度）" class="headerlink" title="多线程打包：（优化打包构建速度）"></a>多线程打包：（优化打包构建速度）</h4><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i thread-loader -D</span><br></pre></td></tr></table></figure>

<p>某个任务消耗时间较长会卡顿，多线程可以同一时间干多件事，效率更高。</p>
<ul>
<li>优点：提升打包速度</li>
<li>缺点：每个进程的开启和交流都会有开销</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  test: <span class="regexp">/\.js$/</span>,</span><br><span class="line">  exclude: <span class="regexp">/node_modules/</span>,</span><br><span class="line">  use: [</span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">   	进程启动大概为600ms，进程通信也有开销</span></span><br><span class="line"><span class="comment">   	只有工作消耗时间比较长，才需要多线程打包</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">    &#123;</span><br><span class="line">      loader: <span class="string">&#x27;thread-loader&#x27;</span>,</span><br><span class="line">      options: &#123;</span><br><span class="line">        worker: <span class="number">2</span>, <span class="comment">// 2个进程</span></span><br><span class="line">      &#125;,</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      loader: <span class="string">&#x27;babel-loader&#x27;</span>,</span><br><span class="line">      options: &#123;</span><br><span class="line">        presets: [</span><br><span class="line">          [</span><br><span class="line">            <span class="string">&#x27;@babel/preset-env&#x27;</span>,</span><br><span class="line">            &#123;</span><br><span class="line">              useBuiltIns: <span class="string">&#x27;usage&#x27;</span>,</span><br><span class="line">              corejs: &#123; <span class="attr">version</span>: <span class="number">3</span> &#125;,</span><br><span class="line">              targets: &#123;</span><br><span class="line">                chrome: <span class="string">&#x27;60&#x27;</span>,</span><br><span class="line">                ie: <span class="string">&#x27;9&#x27;</span>,</span><br><span class="line">              &#125;,</span><br><span class="line">            &#125;,</span><br><span class="line">          ],</span><br><span class="line">        ],</span><br><span class="line">        <span class="comment">// 开启babel缓存；第二次构建，会读取之前的缓存</span></span><br><span class="line">        cacheDirectory: <span class="literal">true</span>,</span><br><span class="line">      &#125;,</span><br><span class="line">    &#125;,</span><br><span class="line">  ],</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>

<h4 id="externals：排除打包（优化打包构建速度）"><a href="#externals：排除打包（优化打包构建速度）" class="headerlink" title="externals：排除打包（优化打包构建速度）"></a>externals：排除打包（优化打包构建速度）</h4><p>externals：让某些库不打包（通过 cdn 引入）</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">externals: &#123;</span><br><span class="line">  <span class="comment">// 拒绝jQuery被打包进来</span></span><br><span class="line">  jquery: <span class="string">&#x27;jQuery&#x27;</span>,</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>

<h4 id="dll：单独打包（优化打包构建速度）"><a href="#dll：单独打包（优化打包构建速度）" class="headerlink" title="dll：单独打包（优化打包构建速度）"></a>dll：单独打包（优化打包构建速度）</h4><ul>
<li>如果使用 cdn 引入，建议使用 externals</li>
<li>如果不使用 cdn 引入，推荐使用 dll</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i add-asset-html-webpack-plugin -D</span><br></pre></td></tr></table></figure>

<p>dll：让某些库单独打包，后直接引入到 build 中</p>
<ul>
<li>可以在 code split 分割出 node_modules 后再用 dll 更细的分割，优化代码运行的性能</li>
<li>使用 dll 技术，对某些库（第三方库：jquery、react、vue…）进行单独打包</li>
</ul>
<p>webpack.dll.js 配置：（将 jquery 单独打包）</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> &#123; resolve &#125; = <span class="built_in">require</span>(<span class="string">&#x27;path&#x27;</span>)</span><br><span class="line"><span class="keyword">const</span> webpack = <span class="built_in">require</span>(<span class="string">&#x27;webpack&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">  entry: &#123;</span><br><span class="line">    <span class="comment">// 最终打包生成的[name]-&gt;jquery</span></span><br><span class="line">    jquery: [<span class="string">&#x27;jquery&#x27;</span>],</span><br><span class="line">  &#125;,</span><br><span class="line">  output: &#123;</span><br><span class="line">    filename: <span class="string">&#x27;[name].js&#x27;</span>,</span><br><span class="line">    path: resolve(__dirname, <span class="string">&#x27;dll&#x27;</span>),</span><br><span class="line">    <span class="comment">// 打包的库里面向外暴露出去的内容叫什么名字 jquery_c37977f51e5c1fd27a84</span></span><br><span class="line">    library: <span class="string">&#x27;[name]_[hash]&#x27;</span>,</span><br><span class="line">  &#125;,</span><br><span class="line">  plugins: [</span><br><span class="line">    <span class="comment">// 打包生成一个mainfest.json-&gt;提供和jquery映射</span></span><br><span class="line">    <span class="keyword">new</span> webpack.DllPlugin(&#123;</span><br><span class="line">      <span class="comment">// 映射库的暴露的内容名称</span></span><br><span class="line">      name: <span class="string">&#x27;[name]_[hash]&#x27;</span>,</span><br><span class="line">      <span class="comment">// 输出文件路径</span></span><br><span class="line">      path: resolve(__dirname, <span class="string">&#x27;dll/mainfest.json&#x27;</span>),</span><br><span class="line">    &#125;),</span><br><span class="line">  ],</span><br><span class="line">  mode: <span class="string">&#x27;production&#x27;</span>,</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>webpack.config.js 配置：（告诉 webpack 不需要再打包 jquery，并将之前打包好的 jquery 跟其他打包好的 jquery 跟其他打包好的资源一同输出到 build 目录下）</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> webpack = <span class="built_in">require</span>(<span class="string">&#x27;webpack&#x27;</span>)</span><br><span class="line"><span class="keyword">const</span> AddAssetHtmlWebpackPlugin = <span class="built_in">require</span>(<span class="string">&#x27;add-asset-html-webpack-plugin&#x27;</span>)</span><br><span class="line"></span><br><span class="line">plugins: [</span><br><span class="line">  <span class="keyword">new</span> HtmlWebpackPlugin(&#123;</span><br><span class="line">    template: <span class="string">&#x27;./src/index.html&#x27;</span>,</span><br><span class="line">  &#125;),</span><br><span class="line">  <span class="comment">// 告诉webpack哪些库不参与打包，同时使用时的名称也得变</span></span><br><span class="line">  <span class="keyword">new</span> webpack.DllReferencePlugin(&#123;</span><br><span class="line">    manifest: resolve(__dirname, <span class="string">&#x27;dll/manifest.json&#x27;</span>),</span><br><span class="line">  &#125;),</span><br><span class="line">  <span class="comment">// 将某个文件打包输出到build目录下，并在html中自动引入该资源</span></span><br><span class="line">  <span class="keyword">new</span> AddAssetHtmlWebpackPlugin(&#123;</span><br><span class="line">    filepath: resolve(__dirname, <span class="string">&#x27;dll/jquery.js&#x27;</span>),</span><br><span class="line">  &#125;),</span><br><span class="line">]</span><br></pre></td></tr></table></figure>

<h4 id="缓存："><a href="#缓存：" class="headerlink" title="缓存："></a>缓存：</h4><ul>
<li>babel 缓存：第二次打包构建速度更快（<strong>优化打包构建速度</strong>）</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  test: <span class="regexp">/\.js$/</span>,</span><br><span class="line">  exclude: <span class="regexp">/node_modules/</span>,</span><br><span class="line">  loader: <span class="string">&#x27;babel-loader&#x27;</span>,</span><br><span class="line">  options: &#123;</span><br><span class="line">    presets: [</span><br><span class="line">      [</span><br><span class="line">        <span class="string">&#x27;@babel/preset-env&#x27;</span>,</span><br><span class="line">        &#123;</span><br><span class="line">          useBuiltIns: <span class="string">&#x27;usage&#x27;</span>,</span><br><span class="line">          corejs: &#123; <span class="attr">version</span>: <span class="number">3</span> &#125;,</span><br><span class="line">          targets: &#123;</span><br><span class="line">            chrome: <span class="string">&#x27;60&#x27;</span>,</span><br><span class="line">            ie: <span class="string">&#x27;9&#x27;</span>,</span><br><span class="line">          &#125;,</span><br><span class="line">        &#125;,</span><br><span class="line">      ],</span><br><span class="line">    ],</span><br><span class="line">    <span class="comment">// 开启babel缓存；第二次构建，会读取之前的缓存</span></span><br><span class="line">    cacheDirectory: <span class="literal">true</span>,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>

<ul>
<li>文件资源缓存：上线代码运行缓存更好使用（<strong>优化代码运行性能</strong>）</li>
</ul>
<ol>
<li>hash：每次webpack构建时会生成一个唯一的hash值。不管文件是否有变化它都会变化</li>
<li>chunkhash：如果打包来源于同一个chunk，那么hash值就一样。如果在 js 中引入 css，js 和 css 就会绑定在一起</li>
<li>contenthash：根据文件的内容生成hash值。不同文件hash值一定不一样</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">hash</span></span><br><span class="line"><span class="comment">  问题：因为js和css同时使用一个hash值，如果重新打包，会导致所有缓存失效</span></span><br><span class="line"><span class="comment">chunkhash</span></span><br><span class="line"><span class="comment">  问题：js和css值还是一样的。因为css是在js中被引入的，所以同属于一个chunk</span></span><br><span class="line"><span class="comment">contenthash</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line">output: &#123;</span><br><span class="line">  filename: <span class="string">&#x27;js/built.[contenthash:10].js&#x27;</span>,</span><br><span class="line">  path: resolve(__dirname, <span class="string">&#x27;build&#x27;</span>),</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>

<h4 id="tree-shaking：树摇（优化代码运行性能）"><a href="#tree-shaking：树摇（优化代码运行性能）" class="headerlink" title="tree shaking：树摇（优化代码运行性能）"></a>tree shaking：树摇（优化代码运行性能）</h4><p>去除程序中没有使用的代码，从而使体积更小，请求速度快</p>
<p>前提：</p>
<ol>
<li>必须使用 ES6 模块化</li>
<li>开启 production 环境</li>
</ol>
<p>在 <code>package.json</code> 中配置</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 可能会把css @babel/polyfill 文件都干掉</span></span><br><span class="line">&quot;sideEffects&quot;: false</span><br><span class="line"><span class="comment">// 不会对css、less文件tree shaking</span></span><br><span class="line">&quot;sideEffects&quot;: [&quot;*.css&quot;, &quot;*.less&quot;]</span><br></pre></td></tr></table></figure>

<h4 id="code-split：代码分割（优化代码运行性能）"><a href="#code-split：代码分割（优化代码运行性能）" class="headerlink" title="code split：代码分割（优化代码运行性能）"></a>code split：代码分割（优化代码运行性能）</h4><p>代码分割：将打包输出的一个大的 bundle.js 文件拆分成多个小文件，这样可以并行加载多个文件，比加载一个文件更快</p>
<ol>
<li><p>多入口拆分</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">entry: &#123;</span><br><span class="line">  <span class="comment">// 多入口：有一个入口，最终输出就有一个bundle</span></span><br><span class="line">  main: <span class="string">&#x27;./src/js/index.js&#x27;</span>,</span><br><span class="line">  test: <span class="string">&#x27;./src/js/test.js&#x27;</span>,</span><br><span class="line">&#125;,</span><br><span class="line">output: &#123;</span><br><span class="line">  filename: <span class="string">&#x27;js/[name].[contenthash:10].js&#x27;</span>,</span><br><span class="line">  path: resolve(__dirname, <span class="string">&#x27;build&#x27;</span>),</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>
</li>
<li><p>optimization：</p>
<ul>
<li>可以将 node_modules 中代码单独打包一个 chunk 最终输出</li>
<li>自动分析多入口 chunk 中，有没有公共的文件。如果有会打包成单独一个 chunk（比如两个模块中都引入了 jquery 会被打包成单独的文件）</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">optimization: &#123;</span><br><span class="line">  splitChunks: &#123;</span><br><span class="line">    chunks: <span class="string">&#x27;all&#x27;</span>,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>
</li>
<li><p>import 动态导入语法</p>
<p>通过 js 代码，让某个文件被单独打包成一个 chunk</p>
<p>import 动态导入语法：能将某个文件单独打包</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span>(<span class="comment">/* webpackChunkName: &#x27;test&#x27; */</span> <span class="string">&#x27;./utils&#x27;</span>)</span><br><span class="line">  .then(<span class="function"><span class="params">result</span> =&gt;</span> &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;文件加载成功&#x27;</span>, result)</span><br><span class="line">  &#125;)</span><br><span class="line">  .catch(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;文件加载失败&#x27;</span>)</span><br><span class="line">  &#125;)</span><br></pre></td></tr></table></figure>

</li>
</ol>
<h4 id="lazy-loading：懒加载（优化代码运行性能）"><a href="#lazy-loading：懒加载（优化代码运行性能）" class="headerlink" title="lazy loading：懒加载（优化代码运行性能）"></a>lazy loading：懒加载（优化代码运行性能）</h4><ol>
<li>懒加载：当文件需要使用时才加载</li>
<li>正常加载：并行加载（同一时间加载多个文件）</li>
<li>预加载 prefetch：会在使用之前，提前加载 js 文件。等其他资源加载完毕，浏览器空闲了，再加载资源</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">document</span>.getElementById(<span class="string">&#x27;btn&#x27;</span>).onclick = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">import</span>(<span class="comment">/* webpackChunkName: &#x27;test&#x27;, webpackPrefetch: true */</span> <span class="string">&#x27;./test&#x27;</span>).then(<span class="function">(<span class="params">&#123; mul &#125;</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(mul(<span class="number">4</span>, <span class="number">5</span>))</span><br><span class="line">  &#125;)</span><br><span class="line">  <span class="keyword">import</span>(<span class="string">&#x27;./test&#x27;</span>).then(<span class="function">(<span class="params">&#123; mul &#125;</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(mul(<span class="number">2</span>, <span class="number">5</span>))</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h4 id="PWA：离线可访问技术（优化代码运行性能）"><a href="#PWA：离线可访问技术（优化代码运行性能）" class="headerlink" title="PWA：离线可访问技术（优化代码运行性能）"></a>PWA：离线可访问技术（优化代码运行性能）</h4><p>渐进式网络开发应用程序，使用 serviceworker 和 worker 技术</p>
<ul>
<li>优点：离线也能访问</li>
<li>缺点：兼容性差</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i workbox-webpack-plugin -D</span><br></pre></td></tr></table></figure>

<p>webpack.config.js 中配置：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> workboxWebpackPlugin = <span class="built_in">require</span>(<span class="string">&#x27;workbox-webpack-plugin&#x27;</span>)</span><br><span class="line">plugins: [</span><br><span class="line">  <span class="keyword">new</span> workboxWebpackPlugin.GenerateSW(&#123;</span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">    1.帮助serviceworker快速启动</span></span><br><span class="line"><span class="comment">    2.删除旧的serviceworker</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    生成一个serviceworker配置文件</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">    clientsClaim: <span class="literal">true</span>,</span><br><span class="line">    skipWaiting: <span class="literal">true</span>,</span><br><span class="line">  &#125;),</span><br><span class="line">],</span><br></pre></td></tr></table></figure>

<p>index.js 中还需要写一段代码来激活它的使用</p>
<ol>
<li><p>eslint 不认识 window、navigator 全局变量</p>
<p>解决：需要修改 package.json 中 eslintConfig 配置</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&quot;eslintConfig&quot;: &#123;</span><br><span class="line">  &quot;env&quot;: &#123;</span><br><span class="line">    &quot;browser&quot;: true // 支持浏览器端全局变量</span><br><span class="line">  &#125;</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>
</li>
<li><p>sw 代码必须运行在服务器上</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">npm i serve -g</span><br><span class="line"><span class="comment"># 启动服务器，将build目录下所有资源作为静态资源暴露出去</span></span><br><span class="line">serve -s build</span><br></pre></td></tr></table></figure>

</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//  注册serviceWorker 处理兼容性问题</span></span><br><span class="line"><span class="keyword">if</span> (<span class="string">&#x27;serviceWorker&#x27;</span> <span class="keyword">in</span> navigator) &#123;</span><br><span class="line">  <span class="built_in">window</span>.addEventListener(<span class="string">&#x27;load&#x27;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    navigator.serviceWorker</span><br><span class="line">      .register(<span class="string">&#x27;/service-worker.js&#x27;</span>)</span><br><span class="line">      .then(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">&#x27;sw注册成功&#x27;</span>)</span><br><span class="line">      &#125;)</span><br><span class="line">      .catch(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">&#x27;sw注册失败&#x27;</span>)</span><br><span class="line">      &#125;)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="Webpack-配置详情"><a href="#Webpack-配置详情" class="headerlink" title="Webpack 配置详情"></a>Webpack 配置详情</h2><h3 id="entry"><a href="#entry" class="headerlink" title="entry"></a>entry</h3><ol>
<li><p>string -&gt; <code>entry: &#39;./src/index.js&#39;</code> <strong>单入口</strong></p>
<p>打包形成一个 chunk。输出一个 bundle 文件，此时 chunk 的名称默认是 main</p>
</li>
<li><p>array -&gt; <code>entry: [&#39;./src/index.js&#39;, &#39;./src/add.js&#39;]</code> 多入口</p>
<p>所有入口文件最终只会形成一个 chunk。输出出去只有一个 bundle 文件</p>
<p>只有在 HMR 功能中让 html 热更新生效</p>
</li>
<li><p>object -&gt; <code>entry: &#123; index: &#39;./src/index.js&#39;, add: &#39;./src/add.js&#39; &#125;</code> <strong>多入口</strong></p>
<p>有几个入口文件就形成几个 chunk，输出几个 bundle 文件，此时 chunk 的名称是 key</p>
</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">entry: &#123;</span><br><span class="line">  <span class="comment">// 最终只会形成一个chunk, 输出出去只有一个bundle文件。</span></span><br><span class="line">  index: [<span class="string">&#x27;./src/index.js&#x27;</span>, <span class="string">&#x27;./src/count.js&#x27;</span>],</span><br><span class="line">  <span class="comment">// 形成一个chunk，输出一个bundle文件。</span></span><br><span class="line">  add: <span class="string">&#x27;./src/add.js&#x27;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="output"><a href="#output" class="headerlink" title="output"></a>output</h3><p>library 一般是作为暴露库去使用，通常是结合 dll，将某个库单独打包</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">output: &#123;</span><br><span class="line">  <span class="comment">// 文件名称（指定名称+目录）</span></span><br><span class="line">  filename: <span class="string">&#x27;js/[name].js&#x27;</span>,</span><br><span class="line">  <span class="comment">// 输出文件目录（将来所有资源输出的公共目录）</span></span><br><span class="line">  path: resolve(__dirname, <span class="string">&#x27;build&#x27;</span>),</span><br><span class="line">  <span class="comment">// 所有资源引入公共路径前缀</span></span><br><span class="line">  publicPath: <span class="string">&#x27;/&#x27;</span>,</span><br><span class="line">  <span class="comment">// 非入口chunk的名称</span></span><br><span class="line">  chunkFilename: <span class="string">&#x27;js/[name]_chunk.js&#x27;</span>,</span><br><span class="line">  <span class="comment">// 整个库向外暴露的变量名</span></span><br><span class="line">  library: <span class="string">&#x27;[name]&#x27;</span>,</span><br><span class="line">  <span class="comment">// libraryTarget: &#x27;window&#x27;, // 变量名添加到哪个browser</span></span><br><span class="line">  <span class="comment">// libraryTarget: &#x27;global&#x27;, // 变量名添加到哪个node</span></span><br><span class="line">  <span class="comment">// libraryTarget: &#x27;commonjs&#x27;,</span></span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>

<h3 id="module"><a href="#module" class="headerlink" title="module"></a>module</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">module</span>: &#123;</span><br><span class="line">  rules: [</span><br><span class="line">    &#123;</span><br><span class="line">      test: <span class="regexp">/\.css$/</span>,</span><br><span class="line">      <span class="comment">// 多个loader用use</span></span><br><span class="line">      use: [<span class="string">&#x27;style-loader&#x27;</span>, <span class="string">&#x27;css-loader&#x27;</span>],</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      test: <span class="regexp">/\.js$/</span>,</span><br><span class="line">      <span class="comment">// 排除node_modules下的js文件</span></span><br><span class="line">      exclude: <span class="regexp">/node_modules/</span>,</span><br><span class="line">      <span class="comment">// 只检查src下的js文件</span></span><br><span class="line">      include: resolve(__dirname, <span class="string">&#x27;src&#x27;</span>),</span><br><span class="line">      <span class="comment">// 优先执行</span></span><br><span class="line">      enforce: <span class="string">&#x27;pre&#x27;</span>,</span><br><span class="line">      <span class="comment">// 延后执行</span></span><br><span class="line">      <span class="comment">// enforce: &#x27;post&#x27;,</span></span><br><span class="line">      <span class="comment">// 单个loader用loader</span></span><br><span class="line">      loader: <span class="string">&#x27;eslint-loader&#x27;</span>,</span><br><span class="line">      options: &#123;&#125;,</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="comment">// 以下配置只会生效一个</span></span><br><span class="line">      oneOf: [],</span><br><span class="line">    &#125;,</span><br><span class="line">  ],</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>

<h3 id="resolve"><a href="#resolve" class="headerlink" title="resolve"></a>resolve</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 解析模块的规则</span></span><br><span class="line">resolve: &#123;</span><br><span class="line">  <span class="comment">// 配置解析模块的别名</span></span><br><span class="line">  alias: &#123;</span><br><span class="line">    $css: resolve(__dirname, <span class="string">&#x27;src/css&#x27;</span>),</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="comment">// 配置省略文件路径的后缀名</span></span><br><span class="line">  extensions: [<span class="string">&#x27;.js&#x27;</span>, <span class="string">&#x27;.json&#x27;</span>, <span class="string">&#x27;.jsx&#x27;</span>],</span><br><span class="line">  <span class="comment">// 告诉webpack解析模块去找哪个目录</span></span><br><span class="line">  modules: [resolve(__dirname, <span class="string">&#x27;../node_modules&#x27;</span>), <span class="string">&#x27;node_modules&#x27;</span>],</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>

<h3 id="dev-server"><a href="#dev-server" class="headerlink" title="dev server"></a>dev server</h3><p>正常浏览器和服务器之间有跨域，但是服务器之间没有跨域。代码通过代理服务器运行，所以浏览器和代理服务器之间没有跨域，浏览器把请求发送到代理服务器上，代理服务器再把接收到的响应给浏览器</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line">devServer: &#123;</span><br><span class="line">  <span class="comment">// 运行代码的目录</span></span><br><span class="line">  contentBase: resolve(__dirname, <span class="string">&#x27;build&#x27;</span>),</span><br><span class="line">  <span class="comment">// 监视contentBase目录下的所有文件，一旦文件变化就会reload</span></span><br><span class="line">  watchContentBase: <span class="literal">true</span>,</span><br><span class="line">  watchOptions: &#123;</span><br><span class="line">    <span class="comment">// 忽略文件</span></span><br><span class="line">    ignored: <span class="regexp">/node_modules/</span>,</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="comment">// 启动gzip压缩</span></span><br><span class="line">  compress: <span class="literal">true</span>,</span><br><span class="line">  <span class="comment">// 端口号</span></span><br><span class="line">  port: <span class="number">5000</span>,</span><br><span class="line">  <span class="comment">// 域名</span></span><br><span class="line">  host: <span class="string">&#x27;localhost&#x27;</span>,</span><br><span class="line">  <span class="comment">// 自动打开浏览器</span></span><br><span class="line">  open: <span class="literal">true</span>,</span><br><span class="line">  <span class="comment">// 开启HMR功能</span></span><br><span class="line">  hot: <span class="literal">true</span>,</span><br><span class="line">  <span class="comment">// 不要显示启动服务器日志信息</span></span><br><span class="line">  clientLogLevel: <span class="string">&#x27;none&#x27;</span>,</span><br><span class="line">  <span class="comment">// 除了一些基本启动信息以外，其他内容都不要显示</span></span><br><span class="line">  quiet: <span class="literal">true</span>,</span><br><span class="line">  <span class="comment">// 如果出错了，不要全屏提示</span></span><br><span class="line">  overlay: <span class="literal">false</span>,</span><br><span class="line">  <span class="comment">// 服务器代理-&gt;解决开发环境跨域问题</span></span><br><span class="line">  proxy: &#123;</span><br><span class="line">    <span class="comment">// 一旦devServer(5000)服务器接收到了 /api/xxx 请求，就会把请求转发到另一个服务器(3000)</span></span><br><span class="line">    <span class="string">&#x27;/api&#x27;</span>: &#123;</span><br><span class="line">      target: <span class="string">&#x27;http://localhost:3000&#x27;</span>,</span><br><span class="line">      <span class="comment">// 发送请求时，请求路径重写：将 /api/xxx -&gt; /xxx</span></span><br><span class="line">      pathRewrite: &#123;</span><br><span class="line">        <span class="string">&#x27;^/api&#x27;</span>: <span class="string">&#x27;&#x27;</span>,</span><br><span class="line">      &#125;,</span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>

<h3 id="optimization"><a href="#optimization" class="headerlink" title="optimization"></a>optimization</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i terser-webpack-plugin -D</span><br></pre></td></tr></table></figure>

<p>contenthash 缓存会导致一个问题：修改 a 文件导致 b 文件 contenthash 变化</p>
<p>因为在 index.js，打包后 index.js 记录了 a.js 的 hash 值，而 a.js 改变，其重新打包后的 hash 改变，导致 index.js 文件内容中记录的 a.js 的 hash 也变化，从而重新打包后 index.js 的 hash 值也会变，这样就会缓存失效</p>
<ul>
<li>splitChunks：能帮我们提取一些公共代码，呈单独 chunk 打包</li>
<li>runtimeChunk：解决 splitChunks 出现的一些问题（某个文件 js 修改，会导致其他 js 文件失效）</li>
<li>minimizer：生产环境压缩 js 可以做的更好</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> &#123; resolve &#125; = <span class="built_in">require</span>(<span class="string">&#x27;path&#x27;</span>)</span><br><span class="line"><span class="keyword">const</span> TerserWebpackPlugin = <span class="built_in">require</span>(<span class="string">&#x27;terser-webpack-plugin&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">  output: &#123;</span><br><span class="line">    filename: <span class="string">&#x27;js/[name].[contenthash:10].js&#x27;</span>,</span><br><span class="line">    path: resolve(__dirname, <span class="string">&#x27;build&#x27;</span>),</span><br><span class="line">    chunkFilename: <span class="string">&#x27;js/[name].[contenthash:10]_chunk.js&#x27;</span>,</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  optimization: &#123;</span><br><span class="line">    splitChunks: &#123;</span><br><span class="line">      chunks: <span class="string">&#x27;all&#x27;</span>,</span><br><span class="line"></span><br><span class="line">      <span class="comment">/*</span></span><br><span class="line"><span class="comment">    默认值：可以不写</span></span><br><span class="line"><span class="comment">    // 分割的chunks最小为30kb</span></span><br><span class="line"><span class="comment">    minSize: 30 * 1024,</span></span><br><span class="line"><span class="comment">    // 最大没有限制</span></span><br><span class="line"><span class="comment">    maxSize: 0,</span></span><br><span class="line"><span class="comment">    // 要提取的chunks最少被引用1次</span></span><br><span class="line"><span class="comment">    minChunks: 1,</span></span><br><span class="line"><span class="comment">    // 按需加载时并行加载的文件的最大数量</span></span><br><span class="line"><span class="comment">    maxAsyncRequests: 5,</span></span><br><span class="line"><span class="comment">    // 入口js文件最大并行数量</span></span><br><span class="line"><span class="comment">    maxInitialRequest: 3,</span></span><br><span class="line"><span class="comment">    // 名称连接符</span></span><br><span class="line"><span class="comment">    automaticNameDelimiter: &#x27;~&#x27;,</span></span><br><span class="line"><span class="comment">    // 可以使用命名规则</span></span><br><span class="line"><span class="comment">    name: true,</span></span><br><span class="line"><span class="comment">    // 分割chunk的组</span></span><br><span class="line"><span class="comment">    cacheGroup: &#123;</span></span><br><span class="line"><span class="comment">      // node_modules文件会被打包到vendors组的chunk中</span></span><br><span class="line"><span class="comment">      // 满足上面的公共规则。如：大小超过30kb，至少被引用一次</span></span><br><span class="line"><span class="comment">      vendors: &#123;</span></span><br><span class="line"><span class="comment">        test: /[\\/]node_modules[\\/]/,</span></span><br><span class="line"><span class="comment">        // 优先级</span></span><br><span class="line"><span class="comment">        priority: -10,</span></span><br><span class="line"><span class="comment">      &#125;,</span></span><br><span class="line"><span class="comment">      default: &#123;</span></span><br><span class="line"><span class="comment">        // 要提取的chunk最少被引用2次</span></span><br><span class="line"><span class="comment">        minChunks: 2,</span></span><br><span class="line"><span class="comment">        // 优先级</span></span><br><span class="line"><span class="comment">        priority: -20,</span></span><br><span class="line"><span class="comment">        // 如果当前要打包的模块和之前已经被提取的模块是同一个，就会复用，而不是重新打包模块</span></span><br><span class="line"><span class="comment">        reuseExistingChunk: true,</span></span><br><span class="line"><span class="comment">      &#125;,</span></span><br><span class="line"><span class="comment">    &#125;,</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="comment">// 当前模块记录其他模块的hash，单独打包为一个文件runtime</span></span><br><span class="line">    <span class="comment">// 解决：修改a文件导致b文件的contenthash变化</span></span><br><span class="line">    runtimeChunk: &#123;</span><br><span class="line">      name: <span class="function"><span class="params">entryPoint</span> =&gt;</span> <span class="string">`runtime-<span class="subst">$&#123;entryPoint.name&#125;</span>`</span>,</span><br><span class="line">    &#125;,</span><br><span class="line">    minimizer: [</span><br><span class="line">      <span class="comment">// 配置生产环境的压缩方案：js和css</span></span><br><span class="line">      <span class="keyword">new</span> TerserWebpackPlugin(&#123;</span><br><span class="line">        <span class="comment">// 开启缓存</span></span><br><span class="line">        cache: <span class="literal">true</span>,</span><br><span class="line">        <span class="comment">// 开启多进程打包</span></span><br><span class="line">        parallel: <span class="literal">true</span>,</span><br><span class="line">        <span class="comment">// 启动source-map</span></span><br><span class="line">        sourceMap: <span class="literal">true</span>,</span><br><span class="line">      &#125;),</span><br><span class="line">    ],</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="Webpack-5"><a href="#Webpack-5" class="headerlink" title="Webpack 5"></a>Webpack 5</h2><p>此版本重点关注以下内容：</p>
<ul>
<li>通过持久缓存提高构建性能</li>
<li>使用更好的算法和默认值来改善长期缓存</li>
<li>通过更好的树摇和代码生成来改善捆绑包大小</li>
<li>清除处于怪异状态的内部结构，同时在 v4 中实现功能而不引入任何重大更改</li>
<li>通过引入重大更改来为将来的功能做准备，以使我们能够尽可能长时间地使用 v5</li>
</ul>
<p>下载：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i webpack@next webpack-cli -D</span><br></pre></td></tr></table></figure>

<h3 id="自动删除-Node-js-Polyfills"><a href="#自动删除-Node-js-Polyfills" class="headerlink" title="自动删除 Node.js Polyfills"></a>自动删除 Node.js Polyfills</h3><p>早期，webpack 的目标是允许在浏览器中运行大多数 node.js 模块，但是模块格局发生了变化，许多模块用途主要是为前端目的而编写的。webpack &lt;= 4 附带了许多 node.js 核心模块 polyfill，一旦模块使用任何核心模块（即 crypto 模块），这些模块就会自动应用</p>
<p>尽管这使使用为 node.js 编写的模块变得容易，但它会将这些巨大的 polyfill 添加到包中。在许多情况下，这些 polyfill 是不必要的</p>
<p>webpack 5 会自动停止填充这些核心模块，并专注于与前端兼容的模块</p>
<ul>
<li>尽可能尝试使用与前端兼容的模块</li>
<li>可以为 node.js 核心模块手动添加一个 polyfill。错误消息将提示如何实现该目标</li>
</ul>
<p>Chunk 和模块 ID，添加了用于长期缓存的新算法。在生产模式下默认情况下启用这些功能</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">chunkIds: <span class="string">&quot;deterministic&quot;</span>, <span class="attr">moduleIds</span>: <span class="string">&quot;deterministic&quot;</span></span><br></pre></td></tr></table></figure>

<h3 id="Chunk-ID"><a href="#Chunk-ID" class="headerlink" title="Chunk ID"></a>Chunk ID</h3><p>你可以不用使用 <code>import(/* webpackChunkName: &quot;name&quot; */ &quot;module&quot;)</code> 在开发环境来为 chunk 命名，生产环境还是有必要的</p>
<p>webpack 内部有 chunk 命名规则，不再是以 id(0, 1, 2) 命名了</p>
<h3 id="Tree-Shaking"><a href="#Tree-Shaking" class="headerlink" title="Tree Shaking"></a>Tree Shaking</h3><ol>
<li><p>webpack 现在能够处理对嵌套模块的 tree shaking</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 在生产环境中，inner 模块暴露的 b 会被删除 */</span></span><br><span class="line"><span class="comment">// inner.js</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> a = <span class="number">1</span>;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> b = <span class="number">2</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// module.js</span></span><br><span class="line"><span class="keyword">import</span> * <span class="keyword">as</span> inner <span class="keyword">from</span> <span class="string">&#x27;./inner&#x27;</span>;</span><br><span class="line"><span class="keyword">export</span> &#123; inner &#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// user.js</span></span><br><span class="line"><span class="keyword">import</span> * <span class="keyword">as</span> <span class="built_in">module</span> <span class="keyword">from</span> <span class="string">&#x27;./module&#x27;</span>;</span><br><span class="line"><span class="built_in">console</span>.log(<span class="built_in">module</span>.inner.a);</span><br></pre></td></tr></table></figure>
</li>
<li><p>webpack 现在能够处理多个模块之间的关系</p>
<p>当设置了 <code>&quot;sideEffects: false&quot;</code> 时，一旦发现 <code>test</code> 方法没有使用，不但删除 test，还会删除 <code>&quot;./someting&quot;</code></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123; something &#125; <span class="keyword">from</span> <span class="string">&#x27;./something&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">usingSomething</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> something;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="function"><span class="keyword">function</span> <span class="title">test</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> usingSomething();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>webpack 现在能处理 Commonjs 的 tree shaking</p>
</li>
</ol>
<h3 id="Output"><a href="#Output" class="headerlink" title="Output"></a>Output</h3><p>webpack 4 默认只能输出 ES5 代码</p>
<p>webpack 5 开始新增一个属性 output.ecmaVersion，可以生成 ES5 和 ES6 代码，如：<code>output.ecmaVersion: 2015</code></p>
<h3 id="SplitChunk"><a href="#SplitChunk" class="headerlink" title="SplitChunk"></a>SplitChunk</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// webpack4</span></span><br><span class="line">minSize: <span class="number">30000</span>;</span><br><span class="line"><span class="comment">// webpack5，可以针对js和css明确划分</span></span><br><span class="line">minSize: &#123;</span><br><span class="line">  javascript: <span class="number">30000</span>,</span><br><span class="line">  style: <span class="number">50000</span>,</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="Caching"><a href="#Caching" class="headerlink" title="Caching"></a>Caching</h3><p>缓存将存储到 <code>node_modules/.cache/webpack</code></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 配置缓存</span></span><br><span class="line">cache: &#123;</span><br><span class="line">  <span class="comment">// 磁盘存储</span></span><br><span class="line">  type: <span class="string">&quot;filesystem&quot;</span>,</span><br><span class="line">  buildDependencies: &#123;</span><br><span class="line">    <span class="comment">// 当配置修改时，缓存失效</span></span><br><span class="line">    config: [__filename]</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="监视输出文件"><a href="#监视输出文件" class="headerlink" title="监视输出文件"></a>监视输出文件</h3><p>之前 webpack 总是在第一次构建时输出全部文件，但是监视重新构建时只更新修改的文件</p>
<p>此次更新在第一次构建时会找到输出文件看是否有变化，从而决定要不要输出全部文件</p>
<h3 id="默认值"><a href="#默认值" class="headerlink" title="默认值"></a>默认值</h3><ul>
<li><code>entry: &quot;./src/index.js&quot;</code></li>
<li><code>output.path: path.resolve(__dirname, &quot;dist&quot;)</code></li>
<li><code>output.filename: &quot;[name].js&quot;</code></li>
</ul>
<h2 id="推荐版本"><a href="#推荐版本" class="headerlink" title="推荐版本"></a>推荐版本</h2><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line">&quot;devDependencies&quot;: &#123;</span><br><span class="line">  &quot;@babel/core&quot;: &quot;^7.10.4&quot;,</span><br><span class="line">  &quot;@babel/polyfill&quot;: &quot;^7.10.4&quot;,</span><br><span class="line">  &quot;@babel/preset-env&quot;: &quot;^7.10.4&quot;,</span><br><span class="line">  &quot;add-asset-html-webpack-plugin&quot;: &quot;^3.1.3&quot;,</span><br><span class="line">  &quot;babel&quot;: &quot;^6.23.0&quot;,</span><br><span class="line">  &quot;babel-loader&quot;: &quot;^8.1.0&quot;,</span><br><span class="line">  &quot;core-js&quot;: &quot;^3.6.5&quot;,</span><br><span class="line">  &quot;css-loader&quot;: &quot;^3.6.0&quot;,</span><br><span class="line">  &quot;eslint&quot;: &quot;^6.8.0&quot;,</span><br><span class="line">  &quot;eslint-config-airbnb-base&quot;: &quot;^14.2.0&quot;,</span><br><span class="line">  &quot;eslint-loader&quot;: &quot;^3.0.4&quot;,</span><br><span class="line">  &quot;eslint-plugin-import&quot;: &quot;^2.22.0&quot;,</span><br><span class="line">  &quot;file-loader&quot;: &quot;^5.1.0&quot;,</span><br><span class="line">  &quot;html-loader&quot;: &quot;^0.5.5&quot;,</span><br><span class="line">  &quot;html-webpack-plugin&quot;: &quot;^3.2.0&quot;,</span><br><span class="line">  &quot;jquery&quot;: &quot;^3.5.1&quot;,</span><br><span class="line">  &quot;less&quot;: &quot;^3.11.3&quot;,</span><br><span class="line">  &quot;less-loader&quot;: &quot;^5.0.0&quot;,</span><br><span class="line">  &quot;mini-css-extract-plugin&quot;: &quot;^0.9.0&quot;,</span><br><span class="line">  &quot;optimize-css-assets-webpack-plugin&quot;: &quot;^5.0.3&quot;,</span><br><span class="line">  &quot;postcss-loader&quot;: &quot;^3.0.0&quot;,</span><br><span class="line">  &quot;postcss-preset-env&quot;: &quot;^6.7.0&quot;,</span><br><span class="line">  &quot;style-loader&quot;: &quot;^1.2.1&quot;,</span><br><span class="line">  &quot;terser-webpack-plugin&quot;: &quot;^2.3.5&quot;,</span><br><span class="line">  &quot;thread-loader&quot;: &quot;^2.1.3&quot;,</span><br><span class="line">  &quot;url-loader&quot;: &quot;^3.0.0&quot;,</span><br><span class="line">  &quot;webpack&quot;: &quot;^4.43.0&quot;,</span><br><span class="line">  &quot;webpack-cli&quot;: &quot;^3.3.12&quot;,</span><br><span class="line">  &quot;webpack-dev-server&quot;: &quot;^3.11.0&quot;,</span><br><span class="line">  &quot;workbox-webpack-plugin&quot;: &quot;^5.1.3&quot;</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>

<h2 id="Webpack-问题汇总"><a href="#Webpack-问题汇总" class="headerlink" title="Webpack 问题汇总"></a>Webpack 问题汇总</h2><h3 id="TypeError-this-getOptions-is-not-a-function"><a href="#TypeError-this-getOptions-is-not-a-function" class="headerlink" title="TypeError: this.getOptions is not a function"></a>TypeError: this.getOptions is not a function</h3><ul>
<li>原因：less-loader 安装版本过高（我安装的是 9 版本的）</li>
<li>解决方案：<code>npm i less-loader@6 -D</code> 即可</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">ERROR <span class="keyword">in</span> ./src/index.less (../node_modules/css-loader/dist/cjs.js!../node_modules/less-loader/dist/cjs.js!./src/index.less)</span><br><span class="line">Module build failed (from ../node_modules/less-loader/dist/cjs.js):</span><br><span class="line">TypeError: this.getOptions is not a <span class="keyword">function</span></span><br><span class="line">    at Object.lessLoader (F:\git_demo\Webpack-study\node_modules\less-loader\dist\index.js:19:24)</span><br><span class="line"> @ ./src/index.less 2:12-134 9:17-24 13:15-22</span><br><span class="line"> @ ./src/index.js</span><br></pre></td></tr></table></figure>

<h3 id="ERROR-in-Error-Child-compilation-failed"><a href="#ERROR-in-Error-Child-compilation-failed" class="headerlink" title="ERROR in   Error: Child compilation failed:"></a>ERROR in   Error: Child compilation failed:</h3><ul>
<li>原因：html-loader 安装版本过高（我安装的是 2 版本的）</li>
<li>解决方案：<code>npm i html-loader@0.5 -D</code> 即可</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">ERROR <span class="keyword">in</span>   Error: Child compilation failed:</span><br><span class="line"> Module build failed (from ../node_modules/html-loader/dist/cjs.js):</span><br><span class="line"> TypeError: this.getOptions is not a <span class="keyword">function</span></span><br><span class="line"> - TypeError: this.getOptions is not a <span class="keyword">function</span></span><br><span class="line"> - ModuleBuildError: Module build failed (from ../node_modules/html-loader/dist/cjs.js):</span><br><span class="line"> - TypeError: this.getOptions is not a <span class="keyword">function</span></span><br><span class="line">...</span><br></pre></td></tr></table></figure>

<h3 id="TypeError-Cannot-read-property-‘tap’-of-undefined"><a href="#TypeError-Cannot-read-property-‘tap’-of-undefined" class="headerlink" title="TypeError: Cannot read property ‘tap’ of undefined"></a>TypeError: Cannot read property ‘tap’ of undefined</h3><ul>
<li>原因：html-webpack-plugin 安装版本过高（我安装的是 5 版本的）</li>
<li>解决方案：<code>npm i html-loader@4 -D</code> 即可</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">TypeError: Cannot <span class="built_in">read</span> property <span class="string">&#x27;tap&#x27;</span> of undefined at HtmlWebpackPlugin.apply (F:\git_demo\Webpack-study\node_modules\html-webpack-plugin\index.js:40:31)  </span><br><span class="line">    at webpack (F:\git_demo\Webpack-study\node_modules\webpack\lib\webpack.js:51:13)</span><br><span class="line">    at processOptions (F:\git_demo\Webpack-study\node_modules\webpack-cli\bin\cli.js:272:16)</span><br><span class="line">    at F:\git_demo\Webpack-study\node_modules\webpack-cli\bin\cli.js:364:3</span><br><span class="line">    at Object.parse (F:\git_demo\Webpack-study\node_modules\yargs\yargs.js:576:18)</span><br><span class="line">    at F:\git_demo\Webpack-study\node_modules\webpack-cli\bin\cli.js:49:8</span><br><span class="line">    at Object.&lt;anonymous&gt; (F:\git_demo\Webpack-study\node_modules\webpack-cli\bin\cli.js:366:3)</span><br></pre></td></tr></table></figure>

<h3 id="img-src-”-object-Module-”"><a href="#img-src-”-object-Module-”" class="headerlink" title="img src=”[object Module]”"></a>img <em>src</em>=”[object Module]”</h3><p>因为 <code>url-loader</code> 默认使用 ES6 模块化解析，而 <code>html-loader</code> 引入图片是CommonJS，解析时会出问题：[object Module]</p>
<p>解决：关闭 <code>url-loader</code> 的 ES6 模块化，使用 CommonJS 解析 <code>esModule: false,</code></p>
<h3 id="Module-build-failed-from-node-modules-mini-css-extract-plugin-dist-loader-js"><a href="#Module-build-failed-from-node-modules-mini-css-extract-plugin-dist-loader-js" class="headerlink" title="Module build failed (from ../node_modules/mini-css-extract-plugin/dist/loader.js):"></a>Module build failed (from ../node_modules/mini-css-extract-plugin/dist/loader.js):</h3><ul>
<li>原因：postcss-loader 安装版本过高（我安装的是 6 版本的）</li>
<li>解决方案：<code>npm i postcss-loader@3 -D</code> 即可</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">Module build failed (from ../node_modules/mini-css-extract-plugin/dist/loader.js):</span><br><span class="line">ModuleBuildError: Module build failed (from ../node_modules/postcss-loader/dist/cjs.js):</span><br><span class="line">ValidationError: Invalid options object. PostCSS Loader has been initialized using an options object that does not match the API schema.</span><br><span class="line"> - options has an unknown property <span class="string">&#x27;plugins&#x27;</span>. These properties are valid:</span><br><span class="line">   object &#123; postcssOptions?, execute?, sourceMap?, implementation? &#125;</span><br><span class="line">    at validate (F:\git_demo\Webpack-study\node_modules\postcss-loader\node_modules\schema-utils\dist\validate.js:104:11)</span><br><span class="line">    at Object.loader (F:\git_demo\Webpack-study\node_modules\postcss-loader\dist\index.js:43:29)    </span><br><span class="line">    at F:\git_demo\Webpack-study\node_modules\webpack\lib\NormalModule.js:316:20</span><br><span class="line">    at F:\git_demo\Webpack-study\node_modules\loader-runner\lib\LoaderRunner.js:367:11</span><br><span class="line">    at F:\git_demo\Webpack-study\node_modules\loader-runner\lib\LoaderRunner.js:233:18</span><br><span class="line"> @ ./src/js/index.js 1:0-2</span><br></pre></td></tr></table></figure>


    </div>

    
    
    

	<div>
		  
			
<div class="my_post_copyright clearfix">
  <script src="//cdn.bootcss.com/clipboard.js/1.5.10/clipboard.min.js"></script>
  
  <!-- JS库 sweetalert 可修改路径 -->
  <script src="https://cdn.bootcss.com/jquery/2.0.0/jquery.min.js"></script>
  <script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
  <article class="box-left">
    <img src="https://gitee.com/lilyn/pic/raw/master/logo.jpg">
  </article>
  <article class="box-right">
    <p><span>本文标题:</span><a href="/posts/4317de95/">Webpack（优化和问题）</a></p>
    <p><span>文章作者:</span><a href="/" title="访问 LiLyn 的个人博客">LiLyn</a></p>
    <p><span>原始链接:</span><a href="/posts/4317de95/" title="Webpack（优化和问题）">http://llmysnow.top/posts/4317de95/</a>
    <span class="copy-path"  title="点击复制文章链接"><i class="fa fa-clipboard" data-clipboard-text="http://llmysnow.top/posts/4317de95/"  aria-label="复制成功！"></i></span>
  </p>
    <p><span>许可协议:</span>转载请保留原文链接及作者。</p>  
  </article>
</div>
<script> 
    var clipboard = new Clipboard('.fa-clipboard');
    $(".fa-clipboard").click(function(){
      clipboard.on('success', function(){
        swal({   
          title: "",   
          text: '复制成功',
          icon: "success", 
          showConfirmButton: true
          });
    });
    });  
</script>

		  
	</div>

      <footer class="post-footer">
          <div class="post-tags">
              <a href="/tags/Vue/" rel="tag"><i class="fa fa-tag"></i> Vue</a>
              <a href="/tags/%E9%97%AE%E9%A2%98/" rel="tag"><i class="fa fa-tag"></i> 问题</a>
              <a href="/tags/%E4%BC%98%E5%8C%96/" rel="tag"><i class="fa fa-tag"></i> 优化</a>
              <a href="/tags/webpack/" rel="tag"><i class="fa fa-tag"></i> webpack</a>
          </div>
		 
		<!--post-tags 彩色标签-->
		<script type="text/javascript">
		var tagsall=document.getElementsByClassName("post-tags")
		for (var i = tagsall.length - 1; i >= 0; i--){
			var tags=tagsall[i].getElementsByTagName("a");
			for (var j = tags.length - 1; j >= 0; j--) {
				var r=Math.floor(Math.random()*75+130);
				var g=Math.floor(Math.random()*75+100);
				var b=Math.floor(Math.random()*75+80);
				tags[j].style.background = "rgb("+r+","+g+","+b+")";
				tags[j].style.color = "#fff";
				tags[j].style.padding = "0 10px";
			}
		}                        
		</script>

        


        
    <div class="post-nav">
      <div class="post-nav-item">
    <a href="/posts/643ce53f/" rel="prev" title="Vue 封装自定义表格的选择框组件">
      <i class="fa fa-chevron-left"></i> Vue 封装自定义表格的选择框组件
    </a></div>
      <div class="post-nav-item">
    <a href="/posts/e8c036a5/" rel="next" title="实现JS一些重要的API">
      实现JS一些重要的API <i class="fa fa-chevron-right"></i>
    </a></div>
    </div>
      </footer>
    
  </article>
  
  
  



          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
          <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#Webpack-%E7%AE%80%E4%BB%8B"><span class="nav-text">Webpack 简介</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#webpack-%E6%98%AF%E4%BB%80%E4%B9%88"><span class="nav-text">webpack 是什么</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#webpack-%E4%BA%94%E4%B8%AA%E6%A0%B8%E5%BF%83%E6%A6%82%E5%BF%B5"><span class="nav-text">webpack 五个核心概念</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Webpack-%E5%88%9D%E4%BD%93%E9%AA%8C"><span class="nav-text">Webpack 初体验</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%88%9D%E5%A7%8B%E5%8C%96%E9%85%8D%E7%BD%AE"><span class="nav-text">初始化配置</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%BC%96%E8%AF%91%E6%89%93%E5%8C%85%E5%BA%94%E7%94%A8"><span class="nav-text">编译打包应用</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Webpack-%E7%8E%AF%E5%A2%83%E7%9A%84%E5%9F%BA%E6%9C%AC%E9%85%8D%E7%BD%AE"><span class="nav-text">Webpack 环境的基本配置</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Webpack-%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E7%9A%84%E5%9F%BA%E6%9C%AC%E9%85%8D%E7%BD%AE"><span class="nav-text">Webpack 生产环境的基本配置</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#css-%E5%85%BC%E5%AE%B9%E6%80%A7%E5%A4%84%E7%90%86"><span class="nav-text">css 兼容性处理</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#eslint-%E8%AF%AD%E6%B3%95%E6%A3%80%E6%9F%A5"><span class="nav-text">eslint 语法检查</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#js-%E5%85%BC%E5%AE%B9%E6%80%A7%E5%A4%84%E7%90%86"><span class="nav-text">js 兼容性处理</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#html-%E5%8E%8B%E7%BC%A9"><span class="nav-text">html 压缩</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Webpack-%E4%BC%98%E5%8C%96%E9%85%8D%E7%BD%AE"><span class="nav-text">Webpack 优化配置</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96"><span class="nav-text">开发环境性能优化</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#HMR%EF%BC%9A%EF%BC%88%E4%BC%98%E5%8C%96%E6%89%93%E5%8C%85%E6%9E%84%E5%BB%BA%E9%80%9F%E5%BA%A6%EF%BC%89"><span class="nav-text">HMR：（优化打包构建速度）</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#source-map%EF%BC%9A%EF%BC%88%E4%BC%98%E5%8C%96%E4%BB%A3%E7%A0%81%E8%B0%83%E8%AF%95%EF%BC%89"><span class="nav-text">source-map：（优化代码调试）</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96"><span class="nav-text">生产环境性能优化</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#oneOf%EF%BC%9A%E6%83%B0%E6%80%A7%E5%8C%B9%E9%85%8D%EF%BC%88%E4%BC%98%E5%8C%96%E6%89%93%E5%8C%85%E6%9E%84%E5%BB%BA%E9%80%9F%E5%BA%A6%EF%BC%89"><span class="nav-text">oneOf：惰性匹配（优化打包构建速度）</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#%E5%A4%9A%E7%BA%BF%E7%A8%8B%E6%89%93%E5%8C%85%EF%BC%9A%EF%BC%88%E4%BC%98%E5%8C%96%E6%89%93%E5%8C%85%E6%9E%84%E5%BB%BA%E9%80%9F%E5%BA%A6%EF%BC%89"><span class="nav-text">多线程打包：（优化打包构建速度）</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#externals%EF%BC%9A%E6%8E%92%E9%99%A4%E6%89%93%E5%8C%85%EF%BC%88%E4%BC%98%E5%8C%96%E6%89%93%E5%8C%85%E6%9E%84%E5%BB%BA%E9%80%9F%E5%BA%A6%EF%BC%89"><span class="nav-text">externals：排除打包（优化打包构建速度）</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#dll%EF%BC%9A%E5%8D%95%E7%8B%AC%E6%89%93%E5%8C%85%EF%BC%88%E4%BC%98%E5%8C%96%E6%89%93%E5%8C%85%E6%9E%84%E5%BB%BA%E9%80%9F%E5%BA%A6%EF%BC%89"><span class="nav-text">dll：单独打包（优化打包构建速度）</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#%E7%BC%93%E5%AD%98%EF%BC%9A"><span class="nav-text">缓存：</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#tree-shaking%EF%BC%9A%E6%A0%91%E6%91%87%EF%BC%88%E4%BC%98%E5%8C%96%E4%BB%A3%E7%A0%81%E8%BF%90%E8%A1%8C%E6%80%A7%E8%83%BD%EF%BC%89"><span class="nav-text">tree shaking：树摇（优化代码运行性能）</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#code-split%EF%BC%9A%E4%BB%A3%E7%A0%81%E5%88%86%E5%89%B2%EF%BC%88%E4%BC%98%E5%8C%96%E4%BB%A3%E7%A0%81%E8%BF%90%E8%A1%8C%E6%80%A7%E8%83%BD%EF%BC%89"><span class="nav-text">code split：代码分割（优化代码运行性能）</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#lazy-loading%EF%BC%9A%E6%87%92%E5%8A%A0%E8%BD%BD%EF%BC%88%E4%BC%98%E5%8C%96%E4%BB%A3%E7%A0%81%E8%BF%90%E8%A1%8C%E6%80%A7%E8%83%BD%EF%BC%89"><span class="nav-text">lazy loading：懒加载（优化代码运行性能）</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#PWA%EF%BC%9A%E7%A6%BB%E7%BA%BF%E5%8F%AF%E8%AE%BF%E9%97%AE%E6%8A%80%E6%9C%AF%EF%BC%88%E4%BC%98%E5%8C%96%E4%BB%A3%E7%A0%81%E8%BF%90%E8%A1%8C%E6%80%A7%E8%83%BD%EF%BC%89"><span class="nav-text">PWA：离线可访问技术（优化代码运行性能）</span></a></li></ol></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Webpack-%E9%85%8D%E7%BD%AE%E8%AF%A6%E6%83%85"><span class="nav-text">Webpack 配置详情</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#entry"><span class="nav-text">entry</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#output"><span class="nav-text">output</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#module"><span class="nav-text">module</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#resolve"><span class="nav-text">resolve</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#dev-server"><span class="nav-text">dev server</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#optimization"><span class="nav-text">optimization</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Webpack-5"><span class="nav-text">Webpack 5</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E8%87%AA%E5%8A%A8%E5%88%A0%E9%99%A4-Node-js-Polyfills"><span class="nav-text">自动删除 Node.js Polyfills</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Chunk-ID"><span class="nav-text">Chunk ID</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Tree-Shaking"><span class="nav-text">Tree Shaking</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Output"><span class="nav-text">Output</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#SplitChunk"><span class="nav-text">SplitChunk</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Caching"><span class="nav-text">Caching</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%9B%91%E8%A7%86%E8%BE%93%E5%87%BA%E6%96%87%E4%BB%B6"><span class="nav-text">监视输出文件</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%BB%98%E8%AE%A4%E5%80%BC"><span class="nav-text">默认值</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%8E%A8%E8%8D%90%E7%89%88%E6%9C%AC"><span class="nav-text">推荐版本</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Webpack-%E9%97%AE%E9%A2%98%E6%B1%87%E6%80%BB"><span class="nav-text">Webpack 问题汇总</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#TypeError-this-getOptions-is-not-a-function"><span class="nav-text">TypeError: this.getOptions is not a function</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#ERROR-in-Error-Child-compilation-failed"><span class="nav-text">ERROR in   Error: Child compilation failed:</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#TypeError-Cannot-read-property-%E2%80%98tap%E2%80%99-of-undefined"><span class="nav-text">TypeError: Cannot read property ‘tap’ of undefined</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#img-src-%E2%80%9D-object-Module-%E2%80%9D"><span class="nav-text">img src&#x3D;”[object Module]”</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Module-build-failed-from-node-modules-mini-css-extract-plugin-dist-loader-js"><span class="nav-text">Module build failed (from ..&#x2F;node_modules&#x2F;mini-css-extract-plugin&#x2F;dist&#x2F;loader.js):</span></a></li></ol></li></ol></div>
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="LiLyn"
      src="/images/logo.jpg">
  <p class="site-author-name" itemprop="name">LiLyn</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">70</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/categories/">
          
        <span class="site-state-item-count">10</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/tags/">
          
        <span class="site-state-item-count">162</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
        <a href="https://github.com/llwodexue" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;llwodexue" rel="noopener" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
      </span>
      <span class="links-of-author-item">
        <a href="https://blog.csdn.net/qq_38689395" title="CSDN → https:&#x2F;&#x2F;blog.csdn.net&#x2F;qq_38689395" rel="noopener" target="_blank"><i class="fas fa-copyright fa-fw"></i>CSDN</a>
      </span>
  </div>


  <div class="links-of-blogroll motion-element">
    <div class="links-of-blogroll-title"><i class="fa fa-link fa-fw"></i>
      友情链接
    </div>
    <ul class="links-of-blogroll-list">
        <li class="links-of-blogroll-item">
          <a href="https://scx69.gitee.io/blogs/" title="https:&#x2F;&#x2F;scx69.gitee.io&#x2F;blogs&#x2F;" rel="noopener" target="_blank">花开满城</a>
        </li>
        <li class="links-of-blogroll-item">
          <a href="http://yixin-oss.gitee.io/daytoy/" title="http:&#x2F;&#x2F;yixin-oss.gitee.io&#x2F;daytoy&#x2F;" rel="noopener" target="_blank">daytoy</a>
        </li>
    </ul>
  </div>

      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

        

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2022</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">LiLyn</span>
    <span class="post-meta-divider">|</span>
    <span class="post-meta-item-icon">
      <i class="fa fa-chart-area"></i>
    </span>
    <span title="站点总字数">463k</span>
    <span class="post-meta-divider">|</span>
    <span class="post-meta-item-icon">
      <i class="fa fa-coffee"></i>
    </span>
    <span title="站点阅读时长">7:01</span>
</div>

<!--
  <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.org/" class="theme-link" rel="noopener" target="_blank">NexT.Gemini</a> 强力驱动
  </div>-->

<!--
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
<div class="powered-by">
  <i class="fa fa-user-md"></i>
  <span id="busuanzi_container_site_pv">
    本站访问量:<span id="busuanzi_value_site_pv"></span>次
  </span>
  <span class="post-meta-divider">|</span>
  <span id="busuanzi_container_site_uv">
    本站总访客量：<span id="busuanzi_value_site_uv"></span>人
  </span>
</div>-->

        








      </div>
    </footer>
  </div>

  
  <script src="/lib/anime.min.js"></script>
  <script src="//cdn.jsdelivr.net/npm/lozad@1/dist/lozad.min.js"></script>
  <script src="/lib/velocity/velocity.min.js"></script>
  <script src="/lib/velocity/velocity.ui.min.js"></script>

<script src="/js/utils.js"></script>

<script src="/js/motion.js"></script>


<script src="/js/schemes/pisces.js"></script>


<script src="/js/next-boot.js"></script>




  
  <script>
    (function(){
      var canonicalURL, curProtocol;
      //Get the <link> tag
      var x=document.getElementsByTagName("link");
		//Find the last canonical URL
		if(x.length > 0){
			for (i=0;i<x.length;i++){
				if(x[i].rel.toLowerCase() == 'canonical' && x[i].href){
					canonicalURL=x[i].href;
				}
			}
		}
    //Get protocol
	    if (!canonicalURL){
	    	curProtocol = window.location.protocol.split(':')[0];
	    }
	    else{
	    	curProtocol = canonicalURL.split(':')[0];
	    }
      //Get current URL if the canonical URL does not exist
	    if (!canonicalURL) canonicalURL = window.location.href;
	    //Assign script content. Replace current URL with the canonical URL
      !function(){var e=/([http|https]:\/\/[a-zA-Z0-9\_\.]+\.baidu\.com)/gi,r=canonicalURL,t=document.referrer;if(!e.test(r)){var n=(String(curProtocol).toLowerCase() === 'https')?"https://sp0.baidu.com/9_Q4simg2RQJ8t7jm9iCKT-xh_/s.gif":"//api.share.baidu.com/s.gif";t?(n+="?r="+encodeURIComponent(document.referrer),r&&(n+="&l="+r)):r&&(n+="?l="+r);var i=new Image;i.src=n}}(window);})();
  </script>




  
<script src="/js/local-search.js"></script>













  

  

  <!-- 动态线条背景 -->
  <script type="text/javascript" src="//cdn.bootcss.com/canvas-nest.js/1.0.0/canvas-nest.min.js"></script>
  <!-- 页面点击小红心 -->
  <script type="text/javascript">
	!function(e,t,a){function n(){c(".heart{width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: fixed;}.heart:after{top: -5px;}.heart:before{left: -5px;}"),o(),r()}function r(){for(var e=0;e<d.length;e++)d[e].alpha<=0?(t.body.removeChild(d[e].el),d.splice(e,1)):(d[e].y--,d[e].scale+=.004,d[e].alpha-=.013,d[e].el.style.cssText="left:"+d[e].x+"px;top:"+d[e].y+"px;opacity:"+d[e].alpha+";transform:scale("+d[e].scale+","+d[e].scale+") rotate(45deg);background:"+d[e].color+";z-index:99999");requestAnimationFrame(r)}function o(){var t="function"==typeof e.onclick&&e.onclick;e.onclick=function(e){t&&t(),i(e)}}function i(e){var a=t.createElement("div");a.className="heart",d.push({el:a,x:e.clientX-5,y:e.clientY-5,scale:1,alpha:1,color:s()}),t.body.appendChild(a)}function c(e){var a=t.createElement("style");a.type="text/css";try{a.appendChild(t.createTextNode(e))}catch(t){a.styleSheet.cssText=e}t.getElementsByTagName("head")[0].appendChild(a)}function s(){return"rgb("+~~(255*Math.random())+","+~~(255*Math.random())+","+~~(255*Math.random())+")"}var d=[];e.requestAnimationFrame=function(){return e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(e){setTimeout(e,1e3/60)}}(),n()}(window,document);
  </script>
<script src="/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({"pluginRootPath":"live2dw/","pluginJsPath":"lib/","pluginModelPath":"assets/","tagMode":false,"log":false,"model":{"jsonPath":"/live2dw/assets/hijiki.model.json"},"display":{"position":"right","width":150,"height":300},"mobile":{"show":true},"react":{"opacity":0.7}});</script></body>
</html>